package it.storm.solution;

import java.util.Arrays;

/**
 * 剑指 Offer 61. 扑克牌中的顺子
 * https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/
 */
public class Solutions_Offer_61 {
    public static void main(String[] args) {
//        int[] nums = {1, 2, 3, 4, 5};  // output: true
        int[] nums = {0, 0, 1, 2, 5};  // output: true
//        int[] nums = {9, 10, 4, 0, 9};  // output: false
//        int[] nums = {4, 7, 5, 9, 2};  // output: false

        boolean result = isStraight(nums);
        System.out.println(result);
    }

    /**
     * 排序
     * 题目中说明了 A 不能看做 14，所以 10, J, Q, K, A 不看作是顺子
     */
    public static boolean isStraight2(int[] nums) {
        // 从小到大排序
        Arrays.sort(nums);
        int jokers = 0;
        for (int i = 0; i < 4; i++) {
            if (nums[i] == 0) {
                // 最后计算时，最小值在 nums[jokers] 上，因为最大值不能跟 0(大小王) 比较
                jokers++;
            } else if (nums[i] == nums[i + 1]) {
                // 出现重复扑克牌，不可能再出现顺子
                return false;
            }
        }
        // 同样判断最大值，与大小王之外的最小值比较，差距是否小于等于 4
        return nums[4] - nums[jokers] <= 4;
    }

    public static boolean isStraight(int[] nums) {
        // map[2]，扑克牌 2 已经出现过
        boolean[] map = new boolean[14];
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
        for (int i = 0; i < 5; i++) {
            int num = nums[i];
            if (num == 0) {
                continue;
            }
            if (map[num]) {
                // 出现重复扑克牌，不可能再出现顺子
                return false;
            }
            // 记录为出现过，同时比较最大最小值
            map[num] = true;
            max = Math.max(max, num);
            min = Math.min(min, num);
        }
        // 最大与最小值，是否小于等于 4，若大于 4，不可能组成顺子，若小于 4，说明 5 张牌中有大小王
        // 正好等于 4 时，而 5 张牌中又没有重复元素，那么 5 张牌就是连续的，正好组成顺子
        return max - min <= 4;
    }
}
